package org.chen.flight.service.translate;

import lombok.extern.slf4j.Slf4j;
import org.chen.common.flight.OneWayFlightInfo;
import org.chen.common.flight.RoundTripFlightInfo;
import org.chen.common.translate.dto.BaiduTranslateRequestDTO;
import org.chen.common.translate.dto.BaiduTranslateResponseDTO;
import org.chen.flight.feign.BaiDuTranslateClient;
import org.chen.flight.service.FlightTranslationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class MultiThreadTranslationService implements FlightTranslationService {

    @Autowired
    private BaiDuTranslateClient baiDuTranslateClient;

    private static final int MAX_TRANSLATION_THREADS = 10;

    // 创建固定数量的翻译线程
    private final ExecutorService translationExecutor = Executors.newFixedThreadPool(MAX_TRANSLATION_THREADS, r -> {
        Thread t = new Thread(r, "translation-worker-" + System.currentTimeMillis());
        t.setDaemon(true);
        return t;
    });

    @Override
    public List<String> batchTranslateTexts(List<String> texts, String fromLang, String toLang) {
        if (CollectionUtils.isEmpty(texts)) {
            return new ArrayList<>();
        }

        log.info("开始多线程翻译，文本数量: {}, 线程数: {}", texts.size(), MAX_TRANSLATION_THREADS);
        long startTime = System.currentTimeMillis();

        // 将文本分成MAX_TRANSLATION_THREADS个部分，每个线程处理一部分
        List<List<String>> partitions = partitionTexts(texts);
        List<Future<List<String>>> futures = new ArrayList<>();

        // 提交翻译任务到不同线程
        for (int i = 0; i < partitions.size(); i++) {
            List<String> partition = partitions.get(i);
            int threadId = i;
            
            Future<List<String>> future = translationExecutor.submit(() -> {
                log.info("线程 {} 开始处理 {} 个文本", threadId, partition.size());
                return translateTextsSequentially(partition, fromLang, toLang, threadId);
            });
            
            futures.add(future);
        }

        // 收集所有线程的结果
        List<String> allResults = new ArrayList<>();
        for (Future<List<String>> future : futures) {
            try {
                List<String> threadResults = future.get(120, TimeUnit.SECONDS);
                allResults.addAll(threadResults);
            } catch (Exception e) {
                log.error("获取翻译结果失败", e);
                // 如果某个线程失败，用空字符串占位
                allResults.addAll(Collections.nCopies(10, ""));
            }
        }

        long endTime = System.currentTimeMillis();
        log.info("多线程翻译完成，总耗时: {}ms", endTime - startTime);

        return allResults;
    }

    /**
     * 将文本列表分割成指定数量的部分
     */
    private List<List<String>> partitionTexts(List<String> texts) {
        List<List<String>> partitions = new ArrayList<>();
        int partitionSize = (int) Math.ceil((double) texts.size() / MAX_TRANSLATION_THREADS);

        for (int i = 0; i < texts.size(); i += partitionSize) {
            int endIndex = Math.min(i + partitionSize, texts.size());
            partitions.add(new ArrayList<>(texts.subList(i, endIndex)));
        }

        return partitions;
    }

    /**
     * 单线程顺序翻译文本列表
     */
    private List<String> translateTextsSequentially(List<String> texts, String fromLang, String toLang, int threadId) {
        List<String> results = new ArrayList<>();
        
        for (int i = 0; i < texts.size(); i++) {
            String text = texts.get(i);
            
            if (!StringUtils.hasText(text)) {
                results.add("");
                continue;
            }

            try {
                String translatedText = translateSingleText(text, fromLang, toLang);
                results.add(translatedText);
                
                log.debug("线程 {} 翻译进度: {}/{}", threadId, i + 1, texts.size());
                
                // 每个翻译请求后稍作延迟，避免API限制
                Thread.sleep(200); // 200ms间隔，确保不超过QPS限制
                
            } catch (Exception e) {
                log.error("线程 {} 翻译失败: {}", threadId, text, e);
                results.add(text); // 翻译失败使用原文
            }
        }

        log.info("线程 {} 完成翻译，处理了 {} 个文本", threadId, texts.size());
        return results;
    }

    /**
     * 翻译单个文本（带重试机制）
     */
    private String translateSingleText(String text, String fromLang, String toLang) {
        int maxRetries = 3;
        
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                BaiduTranslateRequestDTO request = new BaiduTranslateRequestDTO();
                request.setFromLang(fromLang);
                request.setToLang(toLang);
                request.setQ(text.trim());

                BaiduTranslateResponseDTO response = baiDuTranslateClient.baiduTranslate(request);

                if (response != null && response.getTransResult() != null && !response.getTransResult().isEmpty()) {
                    String result = response.getTransResult().get(0).getDst();
                    if (attempt > 1) {
                        log.info("重试翻译成功，尝试次数: {}, 文本: {}", attempt, text);
                    }
                    return result;
                } else {
                    log.warn("翻译响应为空，尝试次数: {}, 文本: {}", attempt, text);
                }

            } catch (Exception e) {
                log.warn("翻译请求失败，尝试次数: {}/{}, 文本: {}, 错误: {}", 
                        attempt, maxRetries, text, e.getMessage());
            }

            // 重试前等待
            if (attempt < maxRetries) {
                try {
                    Thread.sleep(1000 * attempt); // 递增延迟
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        log.error("翻译最终失败，使用原文: {}", text);
        return text;
    }

    @Override
    public List<String> prepareTextsForTranslation(OneWayFlightInfo flight) {
        List<String> texts = new ArrayList<>();
        
        texts.add(StringUtils.hasText(flight.getFlightNumber()) ? flight.getFlightNumber() : "");
        texts.add(StringUtils.hasText(flight.getAirline()) ? flight.getAirline() : "");
        texts.add(StringUtils.hasText(flight.getDuration()) ? flight.getDuration() : "");
        texts.add(StringUtils.hasText(flight.getDepartureAirport()) ? flight.getDepartureAirport() : "");
        texts.add(StringUtils.hasText(flight.getArrivalAirport()) ? flight.getArrivalAirport() : "");
        texts.add(StringUtils.hasText(flight.getDepartureCity()) ? flight.getDepartureCity() : "");
        texts.add(StringUtils.hasText(flight.getArrivalCity()) ? flight.getArrivalCity() : "");
        texts.add(StringUtils.hasText(flight.getBaggageInfo()) ? flight.getBaggageInfo() : "");
        
        if (!CollectionUtils.isEmpty(flight.getPurchaseNotes())) {
            texts.add(String.join("；", flight.getPurchaseNotes()));
        } else {
            texts.add("");
        }
        
        return texts;
    }

    @Override
    public List<String> prepareTextsForTranslation(RoundTripFlightInfo flight) {
        List<String> texts = new ArrayList<>();

        // 去程航班信息
        texts.add(StringUtils.hasText(flight.getOutboundFlight().getFlightNumber()) ? flight.getOutboundFlight().getFlightNumber() : "");
        texts.add(StringUtils.hasText(flight.getOutboundFlight().getAirline()) ? flight.getOutboundFlight().getAirline() : "");
        texts.add(StringUtils.hasText(flight.getOutboundFlight().getDuration()) ? flight.getOutboundFlight().getDuration() : "");
        texts.add(StringUtils.hasText(flight.getOutboundFlight().getDepartureAirport()) ? flight.getOutboundFlight().getDepartureAirport() : "");
        texts.add(StringUtils.hasText(flight.getOutboundFlight().getArrivalAirport()) ? flight.getOutboundFlight().getArrivalAirport() : "");
        texts.add(StringUtils.hasText(flight.getOutboundFlight().getDepartureCity()) ? flight.getOutboundFlight().getDepartureCity() : "");
        texts.add(StringUtils.hasText(flight.getOutboundFlight().getArrivalCity()) ? flight.getOutboundFlight().getArrivalCity() : "");

        // 返程航班信息
        texts.add(StringUtils.hasText(flight.getReturnFlight().getFlightNumber()) ? flight.getReturnFlight().getFlightNumber() : "");
        texts.add(StringUtils.hasText(flight.getReturnFlight().getAirline()) ? flight.getReturnFlight().getAirline() : "");
        texts.add(StringUtils.hasText(flight.getReturnFlight().getDuration()) ? flight.getReturnFlight().getDuration() : "");
        texts.add(StringUtils.hasText(flight.getReturnFlight().getDepartureAirport()) ? flight.getReturnFlight().getDepartureAirport() : "");
        texts.add(StringUtils.hasText(flight.getReturnFlight().getArrivalAirport()) ? flight.getReturnFlight().getArrivalAirport() : "");
        texts.add(StringUtils.hasText(flight.getReturnFlight().getDepartureCity()) ? flight.getReturnFlight().getDepartureCity() : "");
        texts.add(StringUtils.hasText(flight.getReturnFlight().getArrivalCity()) ? flight.getReturnFlight().getArrivalCity() : "");

        // 行李信息和购买须知
        texts.add(StringUtils.hasText(flight.getBaggageInfo()) ? flight.getBaggageInfo() : "");
        if (!CollectionUtils.isEmpty(flight.getPurchaseNotes())) {
            texts.add(String.join("；", flight.getPurchaseNotes()));
        } else {
            texts.add("");
        }

        return texts;
    }
    
    /**
     * 关闭线程池
     */
    @PreDestroy
    public void shutdown() {
        translationExecutor.shutdown();
        try {
            if (!translationExecutor.awaitTermination(10, TimeUnit.SECONDS)) {
                translationExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            translationExecutor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}